/**
 * @file pin_demo.c
 *
 */

/*********************
*      INCLUDES
*********************/
#include "lv_watch.h"

#if USE_LV_WATCH_ENGINEER_MODE != 0

/*********************
*      DEFINES
*********************/

/**********************
*      TYPEDEFS
**********************/

/**********************
*  STATIC PROTOTYPES
**********************/
static void pin_set_create(uint8_t oper, uint8_t retries_left);
static void pin_change_old_ok_btn_action(lv_obj_t * btn, lv_event_t event);
static void pin_lock_btn_action(lv_obj_t * btn, lv_event_t event);
static void pin_chg_code_btn_action(lv_obj_t * btn, lv_event_t event);
static void pin_unlock_btn_action(lv_obj_t * btn, lv_event_t event);
static void pin_add_list_btn(lv_obj_t * list, uint16_t txt_id, lv_event_cb_t cb,
                             uint32_t free_num);

/**********************
*  STATIC VARIABLES
**********************/

/**********************
*      MACROS
**********************/

/**********************
 *   GLOBAL FUNCTIONS
 ***********************/
void watch_modem_pin_status_change_ind(MMI_MODEM_PIN_STATUS_TYPE PinReqType)
{
    printf("%s: pin enabled, PinReqType %d\n", __FUNCTION__, PinReqType);
    if(MMI_MODEM_PIN1_REQUIRED == PinReqType) {
        MMI_Modem_Query_Pin_Lock_Info_t pinlockinfo = {0};
        watch_modem_query_pin_lock_info(MMI_MODEM_PIN1, &pinlockinfo);
        printf("%s: enable %d, number of retries left %d\n",
               __FUNCTION__, pinlockinfo.PinEnable, pinlockinfo.RetriesLeft);
        pin_set_create(3, pinlockinfo.RetriesLeft);
    } else {
        printf("%s: not handle PinReqType %d\n", __FUNCTION__, PinReqType);
    }
}

lv_obj_t * engineer_mode_pin_create(lv_obj_t * activity_obj)
{
    if(activity_obj == NULL) {
        lv_watch_activity_ext_t activity_ext;
        memset(&activity_ext, 0, sizeof(lv_watch_activity_ext_t));
        activity_ext.actId = ACT_ID_ENGINEER_MODE_PIN;
        activity_ext.create = engineer_mode_pin_create;
        activity_ext.prepare_destory = NULL;
        activity_obj = lv_watch_creat_activity_obj(&activity_ext);
        LV_ASSERT_MEM(activity_obj);
    }

    lv_obj_t * obj = lv_watch_obj_create(activity_obj);
    LV_ASSERT_MEM(obj);

    if(false == watch_modem_sim_present_check_req()) {
        lv_obj_t * label = lv_label_create(obj, NULL);
        lv_label_set_text_id(label, WATCH_TEXT_ID_NO_SIM_CARD);
        lv_obj_align(label, obj, LV_ALIGN_CENTER, 0, 0);
        return obj;
    }

    MMI_Modem_Query_Pin_Lock_Info_t PinLockQuery = {0};
    watch_modem_query_pin_lock_info(MMI_MODEM_PIN1, &PinLockQuery);
    printf("%s: enable %d, number of retries left %d\n",
           __FUNCTION__, PinLockQuery.PinEnable, PinLockQuery.RetriesLeft);

    lv_obj_t * bg = lv_cont_create(obj, NULL);
    lv_obj_set_click(bg, false);
    lv_obj_set_size(bg, lv_obj_get_width(obj), lv_obj_get_height(obj));
    lv_obj_add_style(bg, LV_CONT_PART_MAIN, &lv_watch_black_tight);
    lv_obj_align(bg, obj, LV_ALIGN_CENTER, 0, 0);

    lv_obj_t * cont = lv_cont_create(bg, NULL);
    lv_obj_set_click(cont, false);
    lv_obj_set_size(cont, lv_obj_get_width(bg), 30);
    lv_obj_add_style(cont, LV_CONT_PART_MAIN, &lv_watch_style_transp);
    lv_obj_align(cont, bg, LV_ALIGN_IN_TOP_MID, 0, 10);
    lv_obj_t * label = lv_label_create(cont, NULL);
    lv_label_set_text_id(label, WATCH_TEXT_ID_EMODE_PIN_SETTING);
    lv_obj_align(label, cont, LV_ALIGN_CENTER, 0, 0);

    lv_obj_t * list = lv_list_create(bg, NULL);
    lv_obj_add_style(list, LV_LIST_PART_BG,  &lv_watch_style_transp);
    if(1 == PinLockQuery.PinEnable) {
        pin_add_list_btn(list, WATCH_TEXT_ID_EMODE_CHANGE_PIN, pin_chg_code_btn_action,
                         PinLockQuery.RetriesLeft);
        pin_add_list_btn(list, WATCH_TEXT_ID_EMODE_UNLOCK_SIM, pin_unlock_btn_action,
                         PinLockQuery.RetriesLeft);
    } else {
        pin_add_list_btn(list, WATCH_TEXT_ID_EMODE_LOCK_SIM, pin_lock_btn_action,
                         PinLockQuery.RetriesLeft);
    }
    lv_obj_align(list, cont, LV_ALIGN_OUT_BOTTOM_MID, 0, 4);
    lv_watch_obj_add_element(list);

    return obj;
}

/**********************
 *   STATIC FUNCTIONS
 **********************/
static lv_obj_t * pin_get_obj(lv_watch_Activity_Id_t act_Id)
{
    lv_obj_t * activity_obj = lv_watch_get_activity_obj(act_Id);
    if(NULL == activity_obj) return NULL;

    lv_obj_t * obj = NULL;
    lv_watch_get_child_obj(activity_obj, lv_watch_obj_signal, &obj);
    return obj;
}

static void * pin_get_ext(lv_watch_Activity_Id_t act_Id)
{
    lv_obj_t * obj = pin_get_obj(act_Id);
    if(NULL == obj) return NULL;

    if(obj) {
        void * ext = lv_obj_get_ext_attr(obj);
        return ext;
    }
    return NULL;
}

static void pin_del_interface(lv_watch_Activity_Id_t act_id)
{
    lv_obj_t * activity_obj = lv_watch_get_activity_obj(act_id);
    if(NULL == activity_obj) return;

    lv_watch_activity_ext_t * ext = lv_obj_get_ext_attr(activity_obj);
    LV_ASSERT_MEM(ext);
    if(ext->prepare_destory) {
        ext->prepare_destory(activity_obj);
    }
    lv_obj_del(activity_obj);

    return;
}

static lv_obj_t * pin_get_list(void)
{
    lv_obj_t * obj = pin_get_obj(ACT_ID_ENGINEER_MODE_PIN);
    lv_obj_t * list = lv_obj_get_child(lv_obj_get_child(obj, NULL), NULL);
    return list;
}

static void pin_warn_task_cb(lv_task_t * task)
{
    lv_pin_set_obj_ext_t * ext =
        (lv_pin_set_obj_ext_t *)pin_get_ext(ACT_ID_ENGINEER_MODE_PIN_SETTING);
    if(ext) lv_obj_del(ext->cont_warn);
}

static void pin_warning(uint16_t text_id)
{
    lv_obj_t * obj = pin_get_obj(ACT_ID_ENGINEER_MODE_PIN_SETTING);
    lv_pin_set_obj_ext_t * ext = (lv_pin_set_obj_ext_t *)lv_obj_get_ext_attr(obj);
    ext->cont_warn = lv_cont_create(obj, NULL);
    lv_obj_set_click(ext->cont_warn, false);
    lv_cont_set_fit(ext->cont_warn, LV_FIT_TIGHT);
    lv_obj_t * label_warn = lv_label_create(ext->cont_warn, NULL);
    lv_label_set_text_id(label_warn, text_id);
    lv_obj_align(ext->cont_warn, obj, LV_ALIGN_CENTER, 0, 10);
    lv_task_t * task = lv_task_create(pin_warn_task_cb, 1000, LV_TASK_PRIO_MID, NULL);
    lv_task_once(task);
}

static void pin_quit_task_cb(lv_task_t * task)
{
    pin_del_interface(ACT_ID_ENGINEER_MODE_PIN_SETTING);
}

static void pin_quit(void)
{
    lv_obj_t * obj = pin_get_obj(ACT_ID_ENGINEER_MODE_PIN_SETTING);
    lv_obj_clean(obj);
    lv_obj_t * label_title = lv_label_create(obj, NULL);
    lv_label_set_text_id(label_title, WATCH_TEXT_ID_EMODE_DONE);
    lv_obj_align(label_title, obj, LV_ALIGN_CENTER, 0, 0);
    lv_task_t * task = lv_task_create(pin_quit_task_cb, 1000, LV_TASK_PRIO_MID, NULL);
    lv_task_once(task);
}

static void pin_all_quit_task_cb(lv_task_t * task)
{
    pin_del_interface(ACT_ID_ENGINEER_MODE_PIN_SETTING);
    pin_del_interface(ACT_ID_ENGINEER_MODE_PIN);
}

static void pin_quit_cme_error(void)
{
    lv_obj_t * obj = pin_get_obj(ACT_ID_ENGINEER_MODE_PIN_SETTING);
    lv_obj_clean(obj);
    lv_obj_t * label_title = lv_label_create(obj, NULL);
    lv_label_set_text(label_title, "Unexpected mistake!");
    lv_obj_align(label_title, obj, LV_ALIGN_CENTER, 0, 0);
    lv_task_t * task = lv_task_create(pin_all_quit_task_cb, 1000, LV_TASK_PRIO_MID, NULL);
    lv_task_once(task);
}

static void pin_set_title(uint16_t text_id, uint8_t retries_left)
{
    lv_pin_set_obj_ext_t * ext =
        (lv_pin_set_obj_ext_t *)pin_get_ext(ACT_ID_ENGINEER_MODE_PIN_SETTING);
    char text[30];
    snprintf(text, 30, "%s%s %d",
             (char *)lv_lang_get_text(text_id),
             (char *)lv_lang_get_text(WATCH_TEXT_ID_EMODE_RETRY),
             retries_left);
    lv_label_set_text(ext->label_title, text);
}

static lv_obj_t * pin_get_btn_chg(lv_obj_t * list)
{
    return lv_list_get_next_btn(list, NULL);
}

static lv_obj_t * pin_get_btn_unlock(lv_obj_t * list)
{
    return lv_list_get_prev_btn(list, NULL);
}

static void pin_lock_ok_btn_action(lv_obj_t * btn, lv_event_t event)
{
    if(LV_EVENT_CLICKED != event) return;

    lv_pin_set_obj_ext_t * ext =
        (lv_pin_set_obj_ext_t *)pin_get_ext(ACT_ID_ENGINEER_MODE_PIN_SETTING);
    const char * text = lv_textarea_get_text(ext->ta_number);
    char * pin = (char *)Hal_Mem_Alloc(strlen(text) + 1);
    Hal_Mem_Copy(pin, text, strlen(text) + 1);
    printf("%s: pin %s\n", __FUNCTION__, pin);

    uint8_t result = watch_modem_enable_or_disable_pin_lock(MMI_MODEM_PIN1, 1, pin);
    printf("%s: result %d\n", __FUNCTION__, result);
    lv_obj_t * list = pin_get_list();
    if(MMI_MODEM_PIN_CHECK_OK == result) {
        lv_list_clean(list);
        pin_add_list_btn(list, WATCH_TEXT_ID_EMODE_CHANGE_PIN, pin_chg_code_btn_action, 3);
        pin_add_list_btn(list, WATCH_TEXT_ID_EMODE_UNLOCK_SIM, pin_unlock_btn_action, 3);

        pin_quit();
    } else {
        if(0 < result) {
            lv_obj_t * btn_lock = lv_list_get_next_btn(list, NULL);
            lv_watch_set_free_num(btn_lock, result);

            pin_set_title(WATCH_TEXT_ID_EMODE_LOCK_SIM, result);
            pin_warning(WATCH_TEXT_ID_EMODE_PASSWORD_ERROR);
        } else {
            pin_quit_cme_error();
        }
    }
}

static void pin_change_new_ok_btn_action(lv_obj_t * btn, lv_event_t event)
{
    if(LV_EVENT_CLICKED != event) return;

    lv_pin_set_obj_ext_t * ext =
        (lv_pin_set_obj_ext_t *)pin_get_ext(ACT_ID_ENGINEER_MODE_PIN_SETTING);
    const char * text = lv_textarea_get_text(ext->ta_number);
    if(0 == strcmp(text, ext->old_pin)) {
        pin_warning(WATCH_TEXT_ID_EMODE_SAME_PASSWORD);
    } else {
        char * new = (char *)Hal_Mem_Alloc(strlen(text) + 1);
        char * old = (char *)Hal_Mem_Alloc(strlen(ext->old_pin) + 1);
        Hal_Mem_Copy(old, ext->old_pin, strlen(ext->old_pin) + 1);
        Hal_Mem_Copy(new, text, strlen(text) + 1);
        uint8_t result = watch_modem_change_sim_pin(MMI_MODEM_PIN1, new, old);
        printf("%s: result %d, new pin %s\n", __FUNCTION__, result, text);
        lv_obj_t * list = pin_get_list();
        lv_obj_t * btn_chg = pin_get_btn_chg(list);
        if(MMI_MODEM_PIN_CHECK_OK == result) {
            lv_watch_set_free_num(btn_chg, 3);

            pin_quit();
        } else {
            if(0 < result) {
                lv_watch_set_free_num(btn_chg, result);

                pin_set_title(WATCH_TEXT_ID_EMODE_INPUT_OLD_PIN, result);
                lv_textarea_set_text(ext->ta_number, ext->old_pin);
                lv_obj_set_event_cb(btn, pin_change_old_ok_btn_action);
                pin_warning(WATCH_TEXT_ID_EMODE_PASSWORD_ERROR);
            } else {
                pin_quit_cme_error();
            }
        }
    }
}

static void pin_change_old_ok_btn_action(lv_obj_t * btn, lv_event_t event)
{
    if(LV_EVENT_CLICKED != event) return;

    lv_pin_set_obj_ext_t * ext =
        (lv_pin_set_obj_ext_t *)pin_get_ext(ACT_ID_ENGINEER_MODE_PIN_SETTING);
    const char * text = lv_textarea_get_text(ext->ta_number);
    Hal_Mem_Copy(ext->old_pin, text, strlen(text) + 1);
    lv_textarea_set_text(ext->ta_number, "");
    lv_label_set_text_id(ext->label_title, WATCH_TEXT_ID_EMODE_INPUT_NEW_PIN);
    lv_obj_set_event_cb(btn, pin_change_new_ok_btn_action);
    printf("%s: old pin %s\n", __FUNCTION__, ext->old_pin);
}

static void pin_unlock_ok_btn_action(lv_obj_t * btn, lv_event_t event)
{
    if(LV_EVENT_CLICKED != event) return;

    lv_pin_set_obj_ext_t * ext =
        (lv_pin_set_obj_ext_t *)pin_get_ext(ACT_ID_ENGINEER_MODE_PIN_SETTING);
    const char * text = lv_textarea_get_text(ext->ta_number);
    char * pin = (char *)Hal_Mem_Alloc(strlen(text) + 1);
    Hal_Mem_Copy(pin, text, strlen(text) + 1);
    printf("%s: pin %s\n", __FUNCTION__, pin);

    uint8_t result = watch_modem_enable_or_disable_pin_lock(MMI_MODEM_PIN1, 0, pin);
    printf("%s: result %d\n", __FUNCTION__, result);
    lv_obj_t * list = pin_get_list();
    if(MMI_MODEM_PIN_CHECK_OK == result) {
        lv_list_clean(list);
        pin_add_list_btn(list, WATCH_TEXT_ID_EMODE_LOCK_SIM, pin_lock_btn_action, 3);

        pin_quit();
    } else {
        if(0 < result) {
            lv_obj_t * btn_unlock = pin_get_btn_unlock(list);
            lv_watch_set_free_num(btn_unlock, result);
            lv_obj_t * btn_chg = pin_get_btn_chg(list);
            lv_watch_set_free_num(btn_chg, result);

            pin_set_title(WATCH_TEXT_ID_EMODE_UNLOCK_SIM, result);
            pin_warning(WATCH_TEXT_ID_EMODE_PASSWORD_ERROR);
        } else {
            pin_quit_cme_error();
        }
    }
}

static void pin_checkout_ok_btn_action(lv_obj_t * btn, lv_event_t event)
{
    if(LV_EVENT_CLICKED != event) return;

    lv_pin_set_obj_ext_t * ext =
        (lv_pin_set_obj_ext_t *)pin_get_ext(ACT_ID_ENGINEER_MODE_PIN_SETTING);
    const char * text = lv_textarea_get_text(ext->ta_number);
    char * pin = (char *)Hal_Mem_Alloc(strlen(text) + 1);
    Hal_Mem_Copy(pin, text, strlen(text) + 1);
    uint8_t result = watch_modem_request_enter_sim_pin(MMI_MODEM_PIN1, pin);
    printf("%s: result %d\n", __FUNCTION__, result);
    if (MMI_MODEM_PIN_CHECK_OK == result) {
        pin_quit();
    } else {
        if(0 < result) {
            pin_set_title(WATCH_TEXT_ID_EMODE_INPUT_PIN, result);
            pin_warning(WATCH_TEXT_ID_EMODE_PASSWORD_ERROR);
        } else {
            pin_quit_cme_error();
        }
    }
}

static void pin_num_btn_action(lv_obj_t * btn, lv_event_t event)
{
    if(LV_EVENT_CLICKED != event) return;

    lv_pin_set_obj_ext_t * ext =
        (lv_pin_set_obj_ext_t *)pin_get_ext(ACT_ID_ENGINEER_MODE_PIN_SETTING);
    char key = lv_watch_get_free_num(btn);
    if(('0' <= key) && ('9' >= key)) {
        lv_textarea_add_char(ext->ta_number, key);
    } else if('d' == key) {
        lv_textarea_del_char(ext->ta_number);
    }
}

static void pin_set_create(uint8_t oper, uint8_t retries_left)
{
    // for oper, 0: lock, 1: change code, 2: unlock, 3: checkout
    if(3 < oper) {
        printf("%s: oper %d error\n", __FUNCTION__, oper);
        return;
    }

    lv_watch_activity_ext_t activity_ext;
    memset(&activity_ext, 0, sizeof(lv_watch_activity_ext_t));
    activity_ext.actId = ACT_ID_ENGINEER_MODE_PIN_SETTING;
    activity_ext.create = NULL;
    activity_ext.prepare_destory = NULL;
    lv_obj_t * activity_obj = lv_watch_creat_activity_obj(&activity_ext);
    LV_ASSERT_MEM(activity_obj);

    lv_obj_t * obj = lv_watch_obj_create(activity_obj);
    LV_ASSERT_MEM(obj);
    lv_pin_set_obj_ext_t * ext = lv_obj_allocate_ext_attr(obj, sizeof(lv_pin_set_obj_ext_t));
    LV_ASSERT_MEM(ext);

    lv_obj_t * bg = lv_cont_create(obj, NULL);
    lv_obj_set_click(bg, false);
    lv_obj_set_size(bg, lv_obj_get_width(obj), lv_obj_get_height(obj));
    lv_obj_add_style(bg, LV_CONT_PART_MAIN, &lv_watch_black_tight);
    lv_obj_align(bg, obj, LV_ALIGN_CENTER, 0, 0);

    lv_obj_t * cont_title = lv_cont_create(bg, NULL);
    lv_obj_set_click(cont_title, false);
    lv_obj_add_style(cont_title, LV_CONT_PART_MAIN, &lv_watch_style_transp);
    lv_cont_set_fit2(cont_title, LV_FIT_NONE, LV_FIT_TIGHT);
    lv_obj_set_width(cont_title, LV_HOR_RES - 20);
    lv_cont_set_layout(cont_title, LV_LAYOUT_ROW_TOP);
    ext->label_title = lv_label_create(cont_title, NULL);
    if(0 == oper) {
        pin_set_title(WATCH_TEXT_ID_EMODE_LOCK_SIM, retries_left);
    } else if(1 == oper) {
        pin_set_title(WATCH_TEXT_ID_EMODE_INPUT_OLD_PIN, retries_left);
    } else if(2 == oper) {
        pin_set_title(WATCH_TEXT_ID_EMODE_UNLOCK_SIM, retries_left);
    } else {
        pin_set_title(WATCH_TEXT_ID_EMODE_INPUT_PIN, retries_left);
    }
    lv_obj_align(ext->label_title, cont_title, LV_ALIGN_CENTER, 0, 0);
    lv_obj_align(cont_title, bg, LV_ALIGN_IN_TOP_MID, 0, 10);

    ext->ta_number = lv_textarea_create(bg, NULL);
    lv_obj_set_style_local_bg_opa(ext->ta_number, LV_TEXTAREA_PART_BG, LV_STATE_DEFAULT,
                                  LV_OPA_COVER);
    lv_obj_set_style_local_bg_color(ext->ta_number, LV_TEXTAREA_PART_BG, LV_STATE_DEFAULT,
                                    lv_color_hsv_to_rgb(0, 11, 18));
    lv_obj_set_style_local_border_color(ext->ta_number, LV_TEXTAREA_PART_CURSOR, LV_STATE_DEFAULT,
                                        LV_COLOR_WHITE);
    lv_obj_set_style_local_border_width(ext->ta_number, LV_TEXTAREA_PART_CURSOR, LV_STATE_DEFAULT, 2);
    lv_obj_set_width(ext->ta_number, LV_HOR_RES * 2 / 3);
    lv_textarea_set_accepted_chars(ext->ta_number, "0123456789");
    lv_textarea_set_max_length(ext->ta_number, PIN_MAX_PASSWORD_LEN);
    lv_textarea_set_one_line(ext->ta_number, true);
    lv_textarea_set_text(ext->ta_number, "");
    lv_obj_align(ext->ta_number, cont_title, LV_ALIGN_OUT_BOTTOM_MID, 0, 4);
    lv_watch_obj_add_element(ext->ta_number);

    lv_coord_t interval_btn_key = 2;
    lv_coord_t btn_w = (lv_obj_get_width(obj) - 20 - 4 * interval_btn_key) / 5;
    lv_coord_t btn_h = (lv_obj_get_height(obj) - ext->ta_number->coords.y2 - 18 -
                        2 * interval_btn_key) / 3;
    lv_obj_t * btn_ok = lv_btn_create(bg, NULL);
    lv_obj_set_style_local_bg_opa(btn_ok, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_COVER);
    lv_obj_set_style_local_bg_color(btn_ok, LV_BTN_PART_MAIN, LV_STATE_DEFAULT,
                                    lv_color_hsv_to_rgb(0, 10, 40));
    lv_obj_set_style_local_radius(btn_ok, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_DPI / 15);
    lv_obj_set_style_local_border_opa(btn_ok, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_70);
    lv_obj_set_style_local_border_width(btn_ok, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 1);
    lv_obj_set_style_local_border_color(btn_ok, LV_BTN_PART_MAIN, LV_STATE_DEFAULT,
                                        LV_COLOR_HEX3(0x111));
    lv_obj_set_style_local_shadow_color(btn_ok, LV_BTN_PART_MAIN, LV_STATE_DEFAULT,
                                        LV_COLOR_HEX3(0x111));
    lv_obj_set_style_local_shadow_width(btn_ok, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_DPI / 30);
    lv_obj_set_style_local_shadow_ofs_y(btn_ok, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 1);

    lv_obj_set_style_local_bg_opa(btn_ok, LV_BTN_PART_MAIN, LV_STATE_PRESSED, LV_OPA_COVER);
    lv_obj_set_style_local_bg_color(btn_ok, LV_BTN_PART_MAIN, LV_STATE_PRESSED,
                                    lv_color_hsv_to_rgb(0, 10, 40));
    lv_obj_set_style_local_radius(btn_ok, LV_BTN_PART_MAIN, LV_STATE_PRESSED, LV_DPI / 15);
    lv_obj_set_style_local_border_opa(btn_ok, LV_BTN_PART_MAIN, LV_STATE_PRESSED, LV_OPA_70);
    lv_obj_set_style_local_border_width(btn_ok, LV_BTN_PART_MAIN, LV_STATE_PRESSED, 1);
    lv_obj_set_style_local_border_color(btn_ok, LV_BTN_PART_MAIN, LV_STATE_PRESSED,
                                        LV_COLOR_HEX3(0x111));
    lv_obj_set_style_local_shadow_color(btn_ok, LV_BTN_PART_MAIN, LV_STATE_PRESSED,
                                        LV_COLOR_HEX3(0x111));
    lv_obj_set_style_local_shadow_width(btn_ok, LV_BTN_PART_MAIN, LV_STATE_PRESSED, LV_DPI / 30);
    lv_obj_set_style_local_shadow_ofs_y(btn_ok, LV_BTN_PART_MAIN, LV_STATE_PRESSED, 1);
    lv_obj_set_size(btn_ok, btn_w + 4, btn_h);
    lv_obj_t * label_ok = lv_label_create(btn_ok, NULL);
    lv_label_set_text_id(label_ok, WATCH_TEXT_ID_OK);
    lv_obj_align(btn_ok, bg, LV_ALIGN_IN_BOTTOM_RIGHT, -8, -10);
    if(0 == oper) {
        lv_obj_set_event_cb(btn_ok, pin_lock_ok_btn_action);
    } else if(1 == oper) {
        lv_obj_set_event_cb(btn_ok, pin_change_old_ok_btn_action);
    } else if(2 == oper) {
        lv_obj_set_event_cb(btn_ok, pin_unlock_ok_btn_action);
    } else if(3 == oper) {
        lv_obj_set_event_cb(btn_ok, pin_checkout_ok_btn_action);
    }
    lv_watch_obj_add_element(btn_ok);

    lv_obj_t * cont_key = lv_cont_create(bg, NULL);
    lv_obj_set_click(cont_key, false);
    lv_coord_t width_cont_key = 4 * btn_w + 3 * interval_btn_key;
    lv_coord_t height_cont_key = 3 * btn_h + 2 * interval_btn_key;
    lv_obj_set_size(cont_key, width_cont_key, height_cont_key);
    lv_obj_align(cont_key, bg, LV_ALIGN_IN_BOTTOM_LEFT, 8, -10);
    lv_obj_add_style(cont_key, LV_CONT_PART_MAIN, &lv_style_transp_tight);

    char * key[11] = {
        "1", "2", "3", "del", "4", "5", "6", "7", "8", "9", "0"
    };
    lv_obj_t * btn_key;
    lv_obj_t * label_key;
    lv_coord_t x_pos = 0;
    lv_coord_t y_pos = 0;
    for(uint8_t i = 0; i < 11; i++) {
        btn_key = lv_btn_create(cont_key, btn_ok);
        lv_obj_set_width(btn_key, btn_w);
        lv_obj_set_pos(btn_key, x_pos, y_pos);

        label_key = lv_label_create(btn_key, NULL);
        lv_label_set_text(label_key, key[i]);

        lv_watch_set_free_num(btn_key, key[i][0]);
        lv_obj_set_event_cb(btn_key, pin_num_btn_action);

        x_pos += btn_w + interval_btn_key;
        if((3 == i) || (6 == i)) {
            x_pos = 0;
            if(3 == i)
                y_pos = btn_h + interval_btn_key;
            else
                y_pos = (btn_h + interval_btn_key) * 2;
        }
        lv_watch_obj_add_element(btn_key);
    }
}

static void pin_lock_btn_action(lv_obj_t * btn, lv_event_t event)
{
    if(LV_EVENT_CLICKED != event) return;

    pin_set_create(0, lv_watch_get_free_num(btn));
}

static void pin_chg_code_btn_action(lv_obj_t * btn, lv_event_t event)
{
    if(LV_EVENT_CLICKED != event) return;

    pin_set_create(1, lv_watch_get_free_num(btn));
}

static void pin_unlock_btn_action(lv_obj_t * btn, lv_event_t event)
{
    if(LV_EVENT_CLICKED != event) return;

    pin_set_create(2, lv_watch_get_free_num(btn));
}

static void pin_add_list_btn(lv_obj_t * list, uint16_t txt_id, lv_event_cb_t cb,
                             uint32_t free_num)
{
    lv_obj_t * btn = lv_list_add_btn(list, NULL, lv_lang_get_text(txt_id));
    lv_obj_add_style(btn, LV_BTN_PART_MAIN, &lv_watch_style_transp);
    lv_obj_set_style_local_radius(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0);
    lv_obj_set_style_local_border_opa(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_COVER);
    lv_obj_set_style_local_border_width(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 1);
    lv_obj_set_style_local_border_color(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
    lv_obj_set_style_local_border_side(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT,
                                       LV_BORDER_SIDE_BOTTOM);
    lv_obj_set_style_local_radius(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, 0);
    lv_obj_set_style_local_border_opa(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, LV_OPA_COVER);
    lv_obj_set_style_local_border_width(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, 1);
    lv_obj_set_style_local_border_color(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, LV_COLOR_WHITE);
    lv_obj_set_style_local_border_side(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED,
                                       LV_BORDER_SIDE_BOTTOM);
    lv_obj_set_style_local_radius(btn, LV_BTN_PART_MAIN, LV_STATE_FOCUSED, 0);
    lv_obj_set_style_local_border_opa(btn, LV_BTN_PART_MAIN, LV_STATE_FOCUSED, LV_OPA_COVER);
    lv_obj_set_style_local_border_width(btn, LV_BTN_PART_MAIN, LV_STATE_FOCUSED, 1);
    lv_obj_set_style_local_border_color(btn, LV_BTN_PART_MAIN, LV_STATE_FOCUSED, LV_COLOR_WHITE);
    lv_obj_set_style_local_border_side(btn, LV_BTN_PART_MAIN, LV_STATE_FOCUSED,
                                       LV_BORDER_SIDE_BOTTOM);
    lv_watch_set_free_num(btn, free_num);
    lv_obj_set_event_cb(btn, cb);
}

#endif /*USE_LV_WATCH_ENGINEER_MODE*/
